/*
 * @FileName: boot_comm.c
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-08-24 13:58:54
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-23 09:11:56
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#include "easy_serial.h"
#include "boot_comm.h"
#include "bsp_uart.h"
#include "boot.h"
#include "boot_flash.h"

void cmd_boot_unlock(uint8_t cmd, uint8_t * buf, uint16_t len, uint8_t rw)
{
    uint8_t data[1] = {0x01};
    if (rw == OPERATE_R) {
        easy_serial_ack(cmd, ACK_SUCCESS, data, 1);
    } else {
        log_debug("boot_unlock..\n");
        easy_serial_ack(cmd, ACK_SUCCESS, NULL, 0);
    }
}

void cmd_boot_jump_boot(uint8_t cmd, uint8_t * buf, uint16_t len, uint8_t rw)
{
    if (rw == OPERATE_R) {
        easy_serial_ack(cmd, ACK_ERROR, NULL, 0); // 不支持读
    } else {
        log_debug("cmd_boot_jump_boot..\n");
        easy_serial_ack(cmd, ACK_SUCCESS, NULL, 0); // 本身已经在BOOT，直接回复SUCCESS
    }
}

void cmd_boot_erase(uint8_t cmd, uint8_t * buf, uint16_t len, uint8_t rw)
{
    if (rw == OPERATE_R) {
        easy_serial_ack(cmd, ACK_ERROR, NULL, 0);
    } else {
        uint8_t res = ACK_SUCCESS;
        if (boot_app_erase() != SUCCESS) {
            res = ACK_ERROR;
        }
        easy_serial_ack(cmd, res, NULL, 0);
    }
}

void cmd_boot_program(uint8_t cmd, uint8_t * buf, uint16_t len, uint8_t rw)
{
    if (rw == OPERATE_R) {
        easy_serial_ack(cmd, ACK_ERROR, NULL, 0); // 不支持读
    } else {
        uint8_t res = ACK_SUCCESS;
        log_debug("cmd_boot_program..\n");
        if (boot_app_program(buf, len) != SUCCESS) {
            res = ACK_ERROR;
        }
        easy_serial_ack(cmd, res, NULL, 0);
    }
}

void cmd_boot_check(uint8_t cmd, uint8_t * buf, uint16_t len, uint8_t rw)
{
    if (rw == OPERATE_R) {
        easy_serial_ack(cmd, ACK_ERROR, NULL, 0); // 不支持读
    } else {
        uint8_t res = ACK_SUCCESS;
        // 对比校验和
        log_debug("cmd_boot_check..\n");
        uint16_t checksum = (buf[0] << 8) + buf[1];
        if (boot_app_check_crc(checksum) == ERROR) {
            res = ACK_ERROR;
        }
        easy_serial_ack(cmd, res, NULL, 0);
    }
}

void cmd_boot_jump_app(uint8_t cmd, uint8_t * buf, uint16_t len, uint8_t rw)
{
    if (rw == OPERATE_R) {
        easy_serial_ack(cmd, ACK_ERROR, NULL, 0); // 不支持读
    } else {
        log_debug("cmd_boot_jump_app..\n");
        RCC_Reset_Flag_Clear();
        __NVIC_SystemReset();
        // easy_serial_ack(cmd, ACK_SUCCESS, NULL, 0);
    }
}

void cmd_run_mode_handle(uint8_t cmd, uint8_t * data, uint16_t len, uint8_t rw)
{
    if (rw == OPERATE_R) {
        uint8_t ack[1];
        ack[0] = 0x00; 
        easy_serial_ack(cmd, ACK_SUCCESS, ack, 1);
    }
}

cmd_obj_t cmd_table[] = {
    {.cmd = CMD_BOOT_UNLOCK,    .len = 1,       .permission = PERMISSION_W,     .handler = cmd_boot_unlock},
    {.cmd = CMD_BOOT_JUMP_BOOT, .len = 1,       .permission = PERMISSION_W,     .handler = cmd_boot_jump_boot},
    {.cmd = CMD_BOOT_ERASE,     .len = 1,       .permission = PERMISSION_W,     .handler = cmd_boot_erase},
    {.cmd = CMD_BOOT_PROG,      .len = 2048,    .permission = PERMISSION_W,     .handler = cmd_boot_program},
    {.cmd = CMD_BOOT_CHECK,     .len = 1,       .permission = PERMISSION_W,     .handler = cmd_boot_check},
    {.cmd = CMD_BOOT_JUMP_APP,  .len = 1,       .permission = PERMISSION_W,     .handler = cmd_boot_jump_app},
    {.cmd = CMD_RUN_MODE,       .permission = PERMISSION_R,   .len = 2,        .handler = cmd_run_mode_handle},
};

void boot_comm_handle(uint8_t * buf, uint32_t len)
{
    easy_serial_process(buf, len, cmd_table, sizeof(cmd_table) / sizeof(cmd_obj_t));
}

void boot_comm_init(void)
{
    // 注册串口接收完成时的回调
    bsp_wifi_uart_callback_register(boot_comm_handle); 
}
